home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume89
/
graphics
/
mandelv2.7
< prev
next >
Wrap
Internet Message Format
|
1989-06-21
|
52KB
Path: xanth!ames!oliveb!sun!swap!page
From: page%swap@Sun.COM (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v89i158: mandelvroom - mandelbrot explorer v2.0, Part07/09
Message-ID: <111392@sun.Eng.Sun.COM>
Date: 21 Jun 89 04:02:04 GMT
Sender: news@sun.Eng.Sun.COM
Lines: 2056
Approved: page@sun.com
Submitted-by: kevin@uts.amdahl.com (Kevin Clague)
Posting-number: Volume 89, Issue 158
Archive-name: graphics/mandelv20.7
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# nav.c
# orbit.c
# orbitint.c
# packer.c
# palette.c
# This is archive 7 of a 9-part kit.
# This archive created: Tue Jun 20 20:45:31 1989
echo "extracting nav.c"
sed 's/^X//' << \SHAR_EOF > nav.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation. This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains the functions to handle MandelVroom's
X * Zoom box which is used for navigation around in the complex plane.
X */
X
X#include "mandp.h"
X
XSHORT BoxSizeX = 3, BoxSizeY = 3, DragSize = 3;
X
Xstatic SHORT HotSpotX, HotSpotY;
X
Xstruct Picture *ZoomedPict;
X
X#define MENUCODE(m,i,s) (SHIFTMENU(m)|SHIFTITEM(i)|SHIFTSUB(s))
X
X/*
X * Picture (project) related commands
X */
X
XZoomInCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Picture *Pict;
X
X Pict = (struct Picture *) Msg->IDCMPWindow->UserData;
X
X switch( Msg->Class ) {
X
X case GADGETDOWN:
X ZoomedPict = Pict;
X
X case MENUPICK:
X Pict->ZoomType = ZOOMIN;
X if ( ! (Pict->Flags & SCROLL_HAPPENED)) {
X CloseZoomBox(Pict);
X SetToPointer();
X State = ZOOMINSTATE;
X }
X break;
X
X case MOUSEBUTTONS:
X if (Msg->Code == SELECTDOWN) {
X if (ZoomedPict->pNode.ln_Type == Pict->pNode.ln_Type) {
X StartZoomBox(ZoomedPict, Pict);
X ResizeZoomCmd(Msg); /* Pass control off to resize routine */
X }
X }
X break;
X }
X}
X
X/*
X * StartZoomOut
X */
XZoomOutCmd( Msg )
X struct IntuiMessage *Msg;
X{
X register struct Picture *Pict;
X
X if (Msg->Class == MENUPICK) {
X Pict = CurPict;
X } else {
X Pict = (struct Picture *) Msg->IDCMPWindow->UserData;
X }
X Pict->ZoomType = ZOOMOUT;
X
X AddHead( &Pict->zList, &Pict->zNode );
X
X Pict->Flags |= ZOOM_BOX_OPEN;
X Pict->DrawPict = Pict;
X
X Pict->NavLeft = Pict->LeftMarg;
X Pict->NavRight = Pict->CountX + Pict->NavLeft - 1;
X Pict->NavTop = Pict->TopMarg;
X Pict->NavBot = Pict->CountY + Pict->NavTop - 1;
X
X ZoomOnOff( Pict );
X}
X
XResizeZoomCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Window *Window;
X struct Picture *Pict;
X
X Window = Msg->IDCMPWindow;
X Pict = (struct Picture *) Window->UserData;
X
X switch( Msg->Class ) {
X
X case MOUSEBUTTONS:
X switch (Msg->Code) {
X
X case SELECTDOWN:
X
X if (State != ZOOMINSTATE)
X ZoomExtras(ZoomedPict);
X AllocLensTemp( ZoomedPict );
X ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X State = RESIZEZOOMSTATE;
X break;
X
X case SELECTUP:
X ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X FreeLensTemp();
X FinishResize(ZoomedPict);
X State = IDLESTATE;
X break;
X }
X break;
X
X case MOUSEMOVE:
X StretchZoomBox( ZoomedPict );
X break;
X }
X}
X
XZoomDragCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Window *Window;
X struct Picture *Pict;
X
X Window = Msg->IDCMPWindow;
X Pict = (struct Picture *) Window->UserData;
X
X switch( Msg->Class ) {
X
X case MOUSEBUTTONS:
X ZoomExtras( ZoomedPict ); /* draw/undraw the extras */
X switch( Msg->Code ) {
X
X case SELECTDOWN: /* start drag */
X AllocLensTemp( ZoomedPict );
X ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X State = ZOOMDRAGSTATE;
X break;
X
X case SELECTUP: /* stop slide */
X FreeLensTemp();
X ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X State = IDLESTATE;
X break;
X }
X break;
X
X case MOUSEMOVE:
X DragZoomBox( ZoomedPict );
X Lens( ZoomedPict );
X break;
X }
X}
X
XPropResizeCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Window *Window;
X struct Picture *Pict;
X
X Window = Msg->IDCMPWindow;
X Pict = (struct Picture *) Window->UserData;
X
X switch( Msg->Class ) {
X
X case MOUSEBUTTONS:
X ZoomExtras( ZoomedPict ); /* draw/undraw the extras */
X switch( Msg->Code ) {
X
X case SELECTDOWN: /* start resize */
X AllocLensTemp( ZoomedPict );
X StartPropStrech( ZoomedPict );
X ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X State = PROPRESIZESTATE;
X break;
X
X case SELECTUP: /* stop resize */
X FreeLensTemp();
X ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X State = IDLESTATE;
X break;
X }
X break;
X
X case MOUSEMOVE:
X PropStretchBox( ZoomedPict );
X Lens( ZoomedPict );
X break;
X }
X}
X
XSetJuliaCmd(Msg)
X struct IntuiMessage *Msg;
X{
X switch( Msg->Class ) {
X
X case MENUPICK:
X SetToPointer();
X ZoomedPict = CurPict;
X State = SETJULIASTATE;
X break;
X
X case GADGETDOWN:
X SetToPointer();
X ZoomedPict = (struct Picture *) Msg->IDCMPWindow->UserData;
X State = SETJULIASTATE;
X break;
X
X case MOUSEBUTTONS:
X if (Msg->Code == SELECTDOWN) {
X
X SetJuliaPt(ZoomedPict,
X (struct Picture *) Msg->IDCMPWindow->UserData);
X State = IDLESTATE;
X }
X break;
X }
X}
X
XQueryHeightCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Window *Window;
X struct Picture *Pict;
X
X Window = Msg->IDCMPWindow;
X Pict = (struct Picture *) Window->UserData;
X
X if (Pict->Flags & SCROLL_HAPPENED)
X return;
X
X switch( Msg->Class ) {
X
X case MOUSEBUTTONS:
X switch( Msg->Code ) {
X /* start query */
X case SELECTDOWN:
X if (Pict->Counts && !(Pict->Flags & NO_RAM_GENERATE)) {
X ShowContour( MouseX, MouseY, 1 );
X ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X State = QUERYHEIGHTSTATE;
X }
X break;
X
X case SELECTUP: /* stop query */
X ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X State = IDLESTATE;
X break;
X }
X break;
X
X case MOUSEMOVE:
X ShowContour( MouseX, MouseY, 0);
X break;
X }
X}
X
Xstatic int OldHeight; /* used to detect title change */
X
XShowContour(MouseX,MouseY,Flag)
X register int MouseX,MouseY;
X register int Flag;
X{
X register struct Picture *Pict;
X
X static char ScreenTitle[80];
X
X int Height;
X float r, i;
X
X Pict = (struct Picture *) CurWind->UserData;
X
X if (Pict == NULL)
X return;
X
X if (MouseX >= Pict->LeftMarg &&
X MouseY >= Pict->TopMarg &&
X MouseX < CurWind->Width - Pict->RightMarg &&
X MouseY < CurWind->Height - Pict->BotMarg) {
X
X Height = HeightPicked(Pict,MouseX,MouseY);
X r = Pict->RealLow + (MouseX - Pict->LeftMarg) * Pict->RealGap;
X i = Pict->ImagLow + (MouseY - Pict->TopMarg) * Pict->ImagGap;
X
X sprintf(ScreenTitle,"Height %3d r %f i %f",
X Height, r, i);
X
X SetWindowTitles( CurWind, (long) -1, ScreenTitle );
X }
X}
X
X/*
X * Start Zoom box
X */
XStartZoomBox( NavPict, DrawPict )
X register struct Picture *NavPict;
X register struct Picture *DrawPict;
X{
X register struct Window *Window = DrawPict->Window;
X
X CloseZoomBox( NavPict);
X
X AddHead( &DrawPict->zList, &NavPict->zNode );
X
X NavPict->Flags |= ZOOM_BOX_OPEN;
X NavPict->DrawPict = DrawPict;
X
X /* Draw first box */
X NavPict->NavTop = NavPict->NavBot = MouseY;
X NavPict->NavLeft = NavPict->NavRight = MouseX;
X
X ZoomBox( NavPict );
X}
X
XStretchZoomBox( Pict )
X register struct Picture *Pict;
X{
X register struct Picture *DrawPict = Pict->DrawPict;
X register LONG Left = DrawPict->CountX + DrawPict->LeftMarg;
X register LONG Top = DrawPict->CountY + DrawPict->TopMarg;
X
X ZoomBox( Pict );
X
X if ( MouseX < Pict->NavLeft )
X MouseX = Pict->NavLeft;
X
X if ( MouseY < Pict->NavTop )
X MouseY = Pict->NavTop;
X
X if ( MouseX > Left )
X MouseX = Left-1;
X
X if ( MouseY > Top )
X MouseY = Top-1;
X
X Pict->NavBot = MouseY;
X Pict->NavRight = MouseX;
X
X Lens( Pict );
X
X ZoomBox( Pict );
X}
X
Xstatic double ZoomAspectRatio;
X
XStartPropStrech( Pict )
X register struct Picture *Pict;
X{
X ZoomAspectRatio = (double) (Pict->NavRight - Pict->NavLeft) /
X (double) (Pict->NavBot - Pict->NavTop);
X}
X
XPropStretchBox( Pict )
X register struct Picture *Pict;
X{
X register LONG Left = Pict->LeftMarg;
X register LONG Top = Pict->DrawPict->CountY + Pict->TopMarg;
X
X register LONG CenterX = Pict->NavRight - Pict->NavLeft;
X register LONG CenterY = Pict->NavBot - Pict->NavTop;
X
X LONG NewLeft,NewRight,NewTop;
X
X ZoomBox( Pict );
X
X CenterX = Pict->NavLeft + CenterX / 2;
X CenterY = Pict->NavTop + CenterY / 2;
X
X if ( MouseX > CenterX-4 ) MouseX = CenterX-4;
X if ( MouseY < CenterY+4 ) MouseY = CenterY+4;
X
X#if 0
X if ( MouseX < Left ) MouseX = Left; /* don't let it flip */
X if ( MouseY > Top ) MouseY = Top;
X#endif
X
X Top = MouseY - CenterY;
X Left = (LONG) ((float) Top * ZoomAspectRatio);
X
X NewLeft = CenterX - Left;
X NewRight = CenterX + Left;
X NewTop = CenterY - Top;
X
X if (NewLeft >= Pict->LeftMarg &&
X NewRight < Pict->DrawPict->Window->Width - Pict->RightMarg &&
X NewTop >= Pict->TopMarg ) {
X
X Pict->NavBot = MouseY;
X Pict->NavTop = NewTop;
X Pict->NavLeft = NewLeft;
X Pict->NavRight = NewRight;
X }
X
X Lens( Pict );
X
X ZoomBox( Pict );
X}
X
X#define MINXBOX (8 << XScale)
X#define MINYBOX (7 << YScale)
X
XFinishResize( Pict )
X struct Picture *Pict;
X{
X register int t;
X
X if (Pict->NavBot < Pict->NavTop) {
X t = Pict->NavBot;
X Pict->NavBot = Pict->NavTop;
X Pict->NavTop = t;
X }
X if (Pict->NavRight < Pict->NavLeft) {
X t = Pict->NavRight;
X Pict->NavRight = Pict->NavLeft;
X Pict->NavLeft = t;
X }
X
X ZoomBox( Pict );
X
X if (Pict->NavRight - Pict->NavLeft < MINXBOX )
X Pict->NavRight = Pict->NavLeft + MINXBOX;
X
X if (Pict->NavBot - Pict->NavTop < MINYBOX )
X Pict->NavBot = Pict->NavTop + MINYBOX;
X
X ZoomOnOff( Pict );
X}
X
XDragZoomBox( Pict )
X register struct Picture *Pict;
X{
X register struct Picture *DrawPict = Pict->DrawPict;
X register LONG Width, Height;
X
X ZoomBox( Pict );
X
X Width = Pict->NavRight - Pict->NavLeft - HotSpotX;
X Height = Pict->NavBot - Pict->NavTop - HotSpotY;
X
X if ( MouseY < 1 )
X MouseY = 1;
X
X if ( MouseX - HotSpotX < DrawPict->LeftMarg )
X MouseX = DrawPict->LeftMarg + HotSpotX;
X
X if ( MouseY - HotSpotY < DrawPict->TopMarg )
X MouseY = DrawPict->TopMarg + HotSpotY;
X
X if ( MouseX + Width >= DrawPict->CountX + DrawPict->LeftMarg )
X MouseX = DrawPict->CountX + DrawPict->LeftMarg - Width;
X
X if ( MouseY + Height >= DrawPict->CountY + DrawPict->TopMarg )
X MouseY = DrawPict->CountY + DrawPict->TopMarg - Height;
X
X Pict->NavLeft = MouseX - HotSpotX;
X Pict->NavTop = MouseY - HotSpotY;
X
X Pict->NavRight = MouseX + Width;
X Pict->NavBot = MouseY + Height;
X
X Lens( Pict );
X
X ZoomBox( Pict );
X}
X
XCloseZoomBox( Pict )
X struct Picture *Pict;
X{
X if (Pict) {
X if (Pict->Flags & ZOOM_BOX_OPEN) {
X ZoomOnOff( Pict );
X Remove( &Pict->zNode );
X Pict->Flags &= ~ZOOM_BOX_OPEN;
X }
X Pict->DrawPict = NULL;
X }
X}
X
XClearZoomBox(Pict)
X struct Picture *Pict;
X{
X CloseZoomBox( Pict );
X ZoomedPict = NULL;
X}
X
XZoomBox( Pict )
X register struct Picture *Pict;
X{
X if ( Pict && Pict->DrawPict && Pict->DrawPict->Window) {
X
X ObtainSemaphore( &Pict->WindowSemi );
X DrawBox( Pict->DrawPict->Window,
X Pict->NavLeft, Pict->NavTop,
X Pict->NavRight, Pict->NavBot );
X ReleaseSemaphore( &Pict->WindowSemi );
X }
X}
X
XZoomExtras( Pict )
X register struct Picture *Pict;
X{
X if ( Pict && Pict->DrawPict && Pict->DrawPict->Window) {
X
X
X ObtainSemaphore( &Pict->WindowSemi );
X DrawExtras( Pict->DrawPict->Window,
X Pict->NavLeft, Pict->NavTop,
X Pict->NavRight, Pict->NavBot );
X ReleaseSemaphore( &Pict->WindowSemi );
X }
X}
X
XZoomOnOff( Pict )
X register struct Picture *Pict;
X{
X ZoomBox( Pict );
X ZoomExtras( Pict );
X}
X
XDrawBox( Window, PLeft, PTop, PRight, PBottom)
X struct Window *Window;
X SHORT PTop, PLeft, PBottom, PRight;
X{
X register struct RastPort *Rp;
X register LONG Top, Left, Right, Bottom;
X
X Rp = Window->RPort;
X
X Top = PTop;
X Left = PLeft;
X Right = PRight;
X Bottom = PBottom;
X
X SetDrMd(Rp, COMPLEMENT);
X /*
X * Draw the new box
X */
X Move(Rp, Left, Top );
X Draw(Rp, Right, Top );
X Draw(Rp, Right, Bottom);
X Draw(Rp, Left, Bottom);
X Draw(Rp, Left, Top+1 );
X
X SetDrMd(Rp, JAM1);
X} /* DrawBox */
X
XDrawExtras( Window, Left, Top, Right, Bottom)
X struct Window *Window;
X SHORT Top, Left, Bottom, Right;
X{
X register struct RastPort *Rp = Window->RPort;
X register LONG ResizeTop = Bottom - ( BoxSizeY << YScale );
X register LONG ResizeLeft = Right - ( BoxSizeX << XScale );
X register LONG BotDrag = Top + ( DragSize << YScale );
X
X SetDrMd(Rp, COMPLEMENT);
X /*
X * Draw Normal Resize gadget
X */
X Move(Rp, (long) Right - 1, ResizeTop );
X Draw(Rp, ResizeLeft, ResizeTop );
X Draw(Rp, ResizeLeft, (long) Bottom - 1);
X
X /*
X * Draw Proportional Resize gadget
X */
X ResizeLeft = Left + ( BoxSizeX << XScale );
X
X Move(Rp, (long) Left + 1, ResizeTop );
X Draw(Rp, ResizeLeft, ResizeTop );
X Draw(Rp, ResizeLeft, (long) Bottom - 1);
X
X /*
X * Drag bar bar / close gadget separator
X */
X Move(Rp, (long) Left + 1, BotDrag );
X Draw(Rp, (long) Right - 1, BotDrag );
X
X Move(Rp, (long) Left + (4 << XScale), (long) Top + 1);
X Draw(Rp, (long) Left + (4 << XScale), BotDrag - 1 );
X
X SetDrMd(Rp, JAM1);
X} /* DrawExtras */
X
X/*
X * ZoomIn
X */
XZoomIn( NavPict )
X register struct Picture *NavPict;
X{
X register struct Picture *DrawPict = NavPict->DrawPict;
X double left, top;
X double right, bot;
X
X double AspectRatio();
X
X double Gap;
X
X if (DrawPict) {
X
X left = (double) (NavPict->NavLeft - DrawPict->LeftMarg);
X top = (double) (NavPict->NavTop - DrawPict->TopMarg);
X right = (double) (NavPict->NavRight - DrawPict->LeftMarg);
X bot = (double) (NavPict->NavBot - DrawPict->TopMarg);
X
X switch( NavPict->ZoomType ) {
X case ZOOMIN:
X
X NavPict->RealHigh = DrawPict->RealLow + DrawPict->RealGap*right;
X NavPict->ImagHigh = DrawPict->ImagLow + DrawPict->ImagGap*bot;
X NavPict->RealLow = DrawPict->RealLow + DrawPict->RealGap*left;
X NavPict->ImagLow = DrawPict->ImagLow + DrawPict->ImagGap*top;
X
X NavPict->Real = DrawPict->Real;
X NavPict->Imag = DrawPict->Imag;
X break;
X
X case ZOOMOUT:
X
X Gap = (DrawPict->ImagHigh - DrawPict->ImagLow) / (bot - top);
X
X NavPict->ImagLow -= top * Gap;
X NavPict->ImagHigh = NavPict->ImagLow +
X (double) NavPict->CountY*Gap;
X
X NavPict->ImagGap = Gap;
X NavPict->RealGap = Gap *= AspectRatio(NavPict);
X
X NavPict->RealLow -= left * Gap;
X NavPict->RealHigh = NavPict->RealLow +
X (double) NavPict->CountX*Gap;
X }
X
X CloseZoomBox( NavPict );
X }
X CalculateGaps( NavPict );
X} /* ZoomIn */
X
X/*
X * Calculate Gaps
X */
XCalculateGaps( Pict )
X register struct Picture *Pict;
X{
X double AspectRatio();
X
X Pict->ImagGap = (Pict->ImagHigh - Pict->ImagLow) / (double) Pict->CountY;
X Pict->RealGap = Pict->ImagGap * AspectRatio( Pict );
X}
X
X/*
X * Apsect Ratio - IEEE
X */
Xdouble
XAspectRatio( Pict )
X register struct Picture *Pict;
X{
X double aspectratio;
X
X if (Pict->ViewModes & HIRES)
X if (Pict->ViewModes & INTERLACE)
X aspectratio = 0.88;
X else
X aspectratio = 0.44;
X else
X if (Pict->ViewModes & INTERLACE)
X aspectratio = 1.76;
X else
X aspectratio = 0.88;
X
X return( aspectratio );
X}
X
X/*
X * Simulate Zoom box gadgets
X */
Xint
XCheckPictZoomBox( NavPict )
X register struct Picture *NavPict;
X{
X register struct Picture *DrawPict = NavPict->DrawPict;
X register struct Window *Window = DrawPict->Window;
X
X register LONG BoxX;
X
X BoxX = BoxSizeX << XScale;
X
X /* is it in the window box? */
X if (MouseX >= NavPict->NavLeft && MouseX <= NavPict->NavRight &&
X MouseY >= NavPict->NavTop && MouseY <= NavPict->NavBot) {
X
X /* is it in the top part? */
X if (MouseY <= NavPict->NavTop + (DragSize << YScale) ) {
X
X /* is it the drag bar? */
X if (MouseX > NavPict->NavLeft + BoxX ) {
X
X HotSpotX = MouseX - NavPict->NavLeft;
X HotSpotY = MouseY - NavPict->NavTop;
X return(ZOOMDRAGHIT);
X
X } else { /* We got the close gadget */
X
X return(ZOOMCLOSEHIT);
X }
X } else {
X
X /* is it the Resize Gadget? */
X if (MouseY >= NavPict->NavBot - ((BoxSizeY + 1) << YScale) ) {
X
X if ( MouseX > NavPict->NavRight - BoxX ) {
X
X return(ZOOMRESIZEHIT);
X
X } else
X if ( MouseX <= NavPict->NavLeft + BoxX ) {
X
X return(PROPRESIZEHIT);
X }
X }
X }
X }
X return(NOTHINGHIT);
X}
X
XSetJuliaPt( ZoomedPict, Pict )
X register struct Picture *ZoomedPict, *Pict;
X{
X register LONG x,y;
X
X if (ZoomedPict && Pict &&
X ZoomedPict->pNode.ln_Type != Pict->pNode.ln_Type) {
X
X x = MouseX - Pict->LeftMarg;
X y = MouseY - Pict->TopMarg;
X
X ZoomedPict->Real = Pict->RealLow + x * Pict->RealGap;
X ZoomedPict->Imag = Pict->ImagLow + y * Pict->ImagGap;
X }
X}
SHAR_EOF
echo "extracting orbit.c"
sed 's/^X//' << \SHAR_EOF > orbit.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation. This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains the functions that open, maintain and
X * close the orbit window.
X */
X
X#define PARSEGOOD 0
X#define PARSEBAD 1
X
X#include "mandp.h"
X#include "parms.h"
X
XSHORT MaxOrbit = 32;
XUBYTE OrbitMode = 1;
X
XUBYTE OrbitOpen;
X
Xstruct NewWindow NewOrbit = {
X 100, 12, /* start position */
X 130,80, /* width, height */
X
X (UBYTE) 0, (UBYTE) NORMALPEN,
X NULL, /* IDCMP flags */
X /* OrbitWind flags */
X WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING | WINDOWDRAG | ACTIVATE |
X NOCAREREFRESH | SMART_REFRESH,
X (struct Gadget *) NULL, /* first gadget */
X (struct Image *) NULL, /* user checkmark */
X (UBYTE *) "Orbit", /* Title */
X (struct Screen *) NULL, /* pointer to screen */
X (struct BitMap *) NULL, /* pointer to superbitmap */
X 20,20,-1,-1, /* sizing */
X CUSTOMSCREEN /* type of screen */
X};
X
Xstruct Window *OrbitWind;
X
XConfOrbMode( subnum )
X int subnum;
X{
X OrbitMode = subnum;
X}
X
XOrbitCmd( msg )
X register struct IntuiMessage *msg;
X{
X static struct Picture *OrbitPict;
X register struct Window *Window;
X
X switch( msg->Class ) {
X case MENUPICK:
X case GADGETDOWN:
X OpenOrbitWind();
X break;
X
X case MOUSEBUTTONS:
X
X Window = (struct Window *) msg->IDCMPWindow;
X
X switch (msg->Code) {
X case SELECTDOWN:
X
X OrbitPict = (struct Picture *) Window->UserData;
X
X if (OrbitPict != NULL &&
X !(OrbitPict->Flags & SCROLL_HAPPENED)) {
X
X ModifyIDCMP( Window,
X (long) Window->IDCMPFlags | MOUSEMOVE );
X DrawOrbit(OrbitPict);
X }
X break;
X
X case SELECTUP:
X
X if (OrbitPict != NULL) {
X
X ModifyIDCMP( Window,
X (long) Window->IDCMPFlags & ~MOUSEMOVE );
X OrbitPict = NULL;
X }
X break;
X }
X break;
X
X case MOUSEMOVE:
X
X if (OrbitPict != NULL) {
X DrawOrbit( OrbitPict );
X }
X break;
X }
X}
X
XDrawOrbit( Pict )
X struct Picture *Pict;
X{
X switch( OrbitMode ) {
X case 1: /* ffp */
X { /* 32 bit IEEE float variables */
X
X float CReal_float, CImag_float, ZReal_float, ZImag_float;
X
X if (OpenFFPLibs() != 0)
X return;
X
X /* convert 64 bit IEEE variables into 32 bit IEEE variables */
X
X CReal_float =
X Pict->RealLow + (MouseX-Pict->LeftMarg) * Pict->RealGap;
X CImag_float =
X Pict->ImagLow + (MouseY-Pict->TopMarg) * Pict->ImagGap;
X
X ZReal_float = Pict->Real;
X ZImag_float = Pict->Imag;
X
X /*
X * calculate pointers and convert them to pointers to ULONG
X * so that when we indirect off of these and pass the results
X * as parameters they are not promoted to doubles.
X */
X
X DrawOrbitFFP( Pict,
X *((ULONG *) &CReal_float),
X *((ULONG *) &CImag_float),
X *((ULONG *) &ZReal_float),
X *((ULONG *) &ZImag_float));
X }
X break;
X
X case 0: /* int 16/32 */
X DrawOrbitInt( Pict );
X break;
X
X case 2: /* ieee */
X DrawOrbitIEEE( Pict );
X break;
X }
X}
X
Xstruct Gadget *
XMakeOrbitGads()
X{
X register struct Gadget *Firstgadget;
X register struct IntuiText *Intui;
X
X struct IntuiText *ShadowIntui();
X struct Border *Border, *MakeShadow();
X
X Firstgadget = MakeBool(-15,TOPMARG, 12,12, 0,ORBTTYPE<<WINDTYPEBITS,NULL);
X
X if (Firstgadget == NULL) {
X return( Firstgadget );
X }
X
X Firstgadget->Flags |= GRELRIGHT;
X Firstgadget->Activation |= RIGHTBORDER;
X
X Intui = ShadowIntui( "O", 3, 3);
X
X if (Intui == NULL) {
X FreeGadgets( Firstgadget );
X return( NULL );
X }
X
X Firstgadget->GadgetText = Intui;
X
X#define NUMPATCHCORNERS 5
X
X Border = MakeShadow( NORMALPEN, NUMPATCHCORNERS );
X
X if ( Border ) {
X InitPatch( Border );
X
X Border->NextBorder = (struct Border *) Firstgadget->GadgetRender;
X Firstgadget->GadgetRender = (APTR) Border;
X }
X
X return( Firstgadget );
X}
X
Xstatic struct Gadget *OrbitGadgets;
Xstruct Gadget *OrbitResize;
X
X/*
X * Open the Orbit window
X */
XOpenOrbitWind()
X{
X extern struct Window *OpenMyWind();
X
X register struct Window *Window;
X register struct NewWindow *NewWind;
X
X struct Gadget *gadgets;
X
X if ( OrbitWind == NULL ) {
X
X OrbitGadgets = gadgets = MakeOrbitGads();
X
X if (gadgets == NULL) {
X return( -1 );
X }
X
X Window = OpenMyWind(&NewOrbit, screen, gadgets,
X NewOrbit.Width, NewOrbit.Height );
X
X if (Window == NULL) {
X
X DispErrMsg("Can't open picture window",0);
X FreeGadgets( OrbitGadgets );
X return( -1 );
X
X } else {
X
X OrbitWind = Window;
X MoveResize( Window, &OrbitResize );
X BorderWindow( Window );
X }
X }
X
X OrbitOpen = 1;
X State = ORBITSTATE;
X SetToPointer();
X return( 0 );
X} /* OpenOrbit */
X
X/*
X * Close the Orbit Window
X */
XCloseOrbitWind()
X{
X register struct Window *Window;
X register struct NewWindow *NewWindow;
X
X Window = OrbitWind;
X
X if ( Window != NULL) {
X
X NewOrbit.LeftEdge = Window->LeftEdge;
X NewOrbit.TopEdge = Window->TopEdge;
X NewOrbit.Width = Window->Width;
X NewOrbit.Height = Window->Height;
X
X CloseMyWind(Window, OrbitGadgets );
X
X OrbitWind = NULL;
X OrbitGadgets = NULL;
X }
X}
SHAR_EOF
echo "extracting orbitint.c"
sed 's/^X//' << \SHAR_EOF > orbitint.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation. This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains functions to calculate and draw orbits for
X * fixed point (scaled int) math mode.
X */
X
X#include "mandp.h"
X
X#include "parms.h"
X
Xstatic double x_scale, y_scale;
Xstatic int x_center, y_center;
Xstatic int rightedge,botedge;
Xstatic struct RastPort *Rp;
X
Xextern SHORT MaxOrbit;
X
X#define ORBSHIFT 27
X#define ORBINT(f) ((int)((f)*(double)(1<<ORBSHIFT)))
X
XInitIntOrbit()
X{
X register struct Window *Window;
X register int width, height;
X
X Window = OrbitWind;
X Rp = Window->RPort;
X
X width = (Window->Width-LEFTMARG-RIGHTMARG);
X height = (Window->Height-TOPMARG-BOTMARG);
X
X rightedge = width + LEFTMARG - 1;
X botedge = height + TOPMARG - 1;
X
X x_scale = y_scale = (float) height / (2.0 * (double)(1<<ORBSHIFT));
X
X x_center = width/2 + LEFTMARG;
X y_center = height/2 + TOPMARG;
X}
X
Xstatic char first_flag;
X
XDrawOrbitInt( Pict )
X struct Picture *Pict;
X{
X struct IntPotParms Parms;
X LONG creal, cimag;
X LONG sreal, simag;
X
X InitIntOrbit();
X
X creal = ORBINT( Pict->RealLow + (MouseX-Pict->LeftMarg) * Pict->RealGap );
X cimag = ORBINT( Pict->ImagLow + (MouseY-Pict->TopMarg) * Pict->ImagGap );
X
X sreal = ORBINT( Pict->Real );
X simag = ORBINT( Pict->Imag );
X
X if ( Pict->pNode.ln_Type == MANDPICT ) {
X
X Parms.C_Real = creal;
X Parms.C_Imag = cimag;
X
X Parms.ScreenReal = sreal;
X Parms.ScreenImag = simag;
X } else {
X
X Parms.C_Real = sreal;
X Parms.C_Imag = simag;
X
X Parms.ScreenReal = creal;
X Parms.ScreenImag = cimag;
X }
X
X Parms.MaxIteration = MaxOrbit;
X
X /* Clear the window for next display plot */
X
X SetAPen(Rp, 0);
X RectFill(Rp, LEFTMARG,TOPMARG, rightedge, botedge);
X SetAPen(Rp, HIGHLIGHTPEN);
X
X first_flag = 0;
X
X Orbit3216( &Parms );
X}
X
XPlotIntOrbit( zreal, zimag )
X LONG zreal, zimag;
X{
X int x,y;
X
X x = x_center + (int)((double) zreal * x_scale);
X y = y_center + (int)((double) zimag * y_scale);
X
X if (x >= LEFTMARG && x <= rightedge &&
X y >= TOPMARG && y <= botedge &&
X first_flag == 1 ) {
X
X WritePixel( Rp, x, y );
X }
X first_flag = 1;
X}
X
X/*
X * Orbit display for 32 bit math using 16 bit multiplies.
X * It is written for the 68000 instruction set.
X */
XOrbit3216( Parms )
X
X struct IntPotParms *Parms;
X{
X LONG Height;
X
X register struct IntPotParms *P = Parms;
X
X register LONG cura, curb, cura2, curb2;
X
X#asm
Xheight equ -4
XBits2Shift equ 5
X;
X;
X; d1 - BITS2SHIFT
X; d2 - k
X; d4 - a
X; d5 - b
X; d6 - a2
X; d7 - b2
X;
Xscreenr equ 0
Xscreeni equ 4
Xcurx equ 8
Xcury equ 12
Xmaxi equ 16
X;
X move.l #Bits2Shift,d1
X move.l screenr(a2),d4
X move.l screeni(a2),d5
X move.w maxi(a2),d2
X bra Fposa2
X;
XFKLoop
X;
X; cura = cura2 - curb2 + curx;
X exg d6,d4 ; exchange cura and cura2
X sub.l d7,d4 ; subtract curb
X add.l curx(a2),d4 ; add curx
X;
X; curb = cura * curb >> 12;
X move.l d6,d7 ; get copy of op1 sign bit
X bpl Fpos1 ; get absolute value of op1
X neg.l d6
XFpos1
X eor.l d5,d7 ; calculate result sign
X tst.l d5 ; get absolute value of op2
X bpl Fpos2
X neg.l d5
XFpos2
X move.l d6,d0 ; get a copy of op1
X swap d0 ; get high half of op1
X move.w d0,d7 ; save a copy of high half
X mulu d5,d0 ; multiply op2 low by op1 high
X clr.w d0 ; clear least significant part
X swap d0 ; put it in it's place
X swap d5 ; get high half of op2
X mulu d5,d6 ; multiply op2 high with op1 low
X clr.w d6 ; clear least significant part
X swap d6 ; put it in its place
X mulu d7,d5 ; multiply op2 high by op1 high
X add.l d0,d5 ; add partial results
X add.l d6,d5 ; add partial results
X tst.l d7 ; is the result negative?
X bpl Fpos3
X neg.l d5 ; yes, better negate it.
XFpos3
X asl.l d1,d5 ; now, rescale it.
X;
X; curb += curb + cury;
X add.l d5,d5 ; double it and add cury
X add.l cury(a2),d5
XFposa2
X;
X; cura2 = cura * cura;
X move.l d4,d0 ; get absolute value of a in d0
X bpl Fposa
X neg.l d0
XFposa
X move.l d0,d6 ; copy absolute value into d6
X swap d6 ; get high part in d6
X mulu d6,d0 ; multiply high and low destroying low
X clr.w d0 ; clear the least significant part
X swap d0 ; put most sig. part in low half
X mulu d6,d6 ; multiply high and high destroing high
X add.l d0,d6 ; add in lower half twice
X add.l d0,d6
X asl.l d1,d6 ; get radix point back in correct place
X bvs Fbailout
X;
X; curb2 = curb * curb;
X move.l d5,d0 ; get absolute value of a in d0
X bpl Fposb
X neg.l d0
XFposb
X move.l d0,d7 ; copy absolute value into d7
X swap d7 ; get high part in d7
X mulu d7,d0 ; multiply high and low destroying low
X clr.w d0 ; clear the least significant part
X swap d0 ; put most sig. part in low half
X mulu d7,d7 ; multiply high and high destroing high
X add.l d0,d7 ; add in lower half twice
X add.l d0,d7
X asl.l d1,d7 ; get radix point back in correct place
X bvs Fbailout
X;
X movem.l .saveregs,-(sp)
X;
X#endasm
X PlotIntOrbit(cura,curb);
X#asm
X;
X movem.l (sp)+,.saveregs
X;
X move.l d6,d0 ; if (cura2 + curb2 >= 4) goto bailout;
X add.l d7,d0
X bvs Fbailout
X;
X dbra d2,FKLoop
X; addq #1,d2
XFbailout
X move.w maxi(a2),d0
X sub.w d2,d0
X sub.w #1,d0
X ext.l d0
X#endasm
X ;;
X}
X
X#asm
X.saveregs reg d0-d3/a2
X#endasm
X
X
X
SHAR_EOF
echo "extracting packer.c"
sed 's/^X//' << \SHAR_EOF > packer.c
X/*----------------------------------------------------------------------*
X * packer.c Convert data to "cmpByteRun1" run compression. 11/15/85
X *
X * By Jerry Morrison and Steve Shaw, Electronic Arts.
X * This software is in the public domain.
X *
X * control bytes:
X * [0..127] : followed by n+1 bytes of data.
X * [-1..-127] : followed by byte to be repeated (-n)+1 times.
X * -128 : NOOP.
X *
X * This version for the Commodore-Amiga computer.
X *----------------------------------------------------------------------*/
X#include "iff/packer.h"
X
X#define DUMP 0
X#define RUN 1
X
X#define MinRun 3
X#define MaxRun 128
X#define MaxDat 128
X
XLONG putSize;
X#define GetByte() (*source++)
X#define PutByte(c) { *dest++ = (c); ++putSize; }
X
Xchar buf[256]; /* [TBD] should be 128? on stack?*/
X
XBYTE *PutDump(dest, nn) BYTE *dest; int nn; {
X int i;
X
X PutByte(nn-1);
X for(i = 0; i < nn; i++) PutByte(buf[i]);
X return(dest);
X }
X
XBYTE *PutRun(dest, nn, cc) BYTE *dest; int nn, cc; {
X PutByte(-(nn-1));
X PutByte(cc);
X return(dest);
X }
X
X#define OutDump(nn) dest = PutDump(dest, nn)
X#define OutRun(nn,cc) dest = PutRun(dest, nn, cc)
X
X/*----------- PackRow --------------------------------------------------*/
X/* Given POINTERS TO POINTERS, packs one row, updating the source and
X destination pointers. RETURNs count of packed bytes.*/
XLONG PackRow(pSource, pDest, rowSize)
X BYTE **pSource, **pDest; LONG rowSize; {
X BYTE *source, *dest;
X char c,lastc = '\0';
X BOOL mode = DUMP;
X short nbuf = 0; /* number of chars in buffer */
X short rstart = 0; /* buffer index current run starts */
X
X source = *pSource;
X dest = *pDest;
X putSize = 0;
X buf[0] = lastc = c = GetByte(); /* so have valid lastc */
X nbuf = 1; rowSize--; /* since one byte eaten.*/
X
X
X for (; rowSize; --rowSize) {
X buf[nbuf++] = c = GetByte();
X switch (mode) {
X case DUMP:
X /* If the buffer is full, write the length byte,
X then the data */
X if (nbuf>MaxDat) {
X OutDump(nbuf-1);
X buf[0] = c;
X nbuf = 1; rstart = 0;
X break;
X }
X
X if (c == lastc) {
X if (nbuf-rstart >= MinRun) {
X if (rstart > 0) OutDump(rstart);
X mode = RUN;
X }
X else if (rstart == 0)
X mode = RUN; /* no dump in progress,
X so can't lose by making these 2 a run.*/
X }
X else rstart = nbuf-1; /* first of run */
X break;
X
X case RUN: if ( (c != lastc)|| ( nbuf-rstart > MaxRun)) {
X /* output run */
X OutRun(nbuf-1-rstart,lastc);
X buf[0] = c;
X nbuf = 1; rstart = 0;
X mode = DUMP;
X }
X break;
X }
X
X lastc = c;
X }
X
X switch (mode) {
X case DUMP: OutDump(nbuf); break;
X case RUN: OutRun(nbuf-rstart,lastc); break;
X }
X *pSource = source;
X *pDest = dest;
X return(putSize);
X }
X
SHAR_EOF
echo "extracting palette.c"
sed 's/^X//' << \SHAR_EOF > palette.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation. This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains the functions that open, maintain, operate
X * and close the color palette.
X */
X
X#include "mandp.h"
X
X#include <ctype.h>
X
X#define PENLEFT 8
X#define PENTOP 15
X
Xextern struct Gadget *ContGadget[], *SelGadget[];
X
XUBYTE PaletteOpen;
X
X/*
X * Holder for Allocated color potentiometer gadgets.
X */
Xstruct ColorGads {
X struct Gadget *RedPot;
X struct Gadget *GreenPot;
X struct Gadget *BluePot;
X};
X
Xstruct Window *PalWind;
Xstruct ColorGads PalGads;
X
XLONG CurPen;
X
Xstruct NewWindow NewPal = {
X 128,0, /* start position */
X 70,80, /* width, height */
X (UBYTE) 0, (UBYTE) -1, /* detail pen, block pen */
X NULL, /* IDCMP flags */
X /* MandWind flags */
X WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH,
X (struct Gadget *) NULL, /* first gadget */
X (struct Image *) NULL, /* user checkmark */
X (UBYTE *) "Colors", /* window title */
X (struct Screen *) NULL, /* pointer to screen */
X (struct BitMap *) NULL, /* pointer to superbitmap */
X 80,80,80,80, /* sizing */
X CUSTOMSCREEN /* type of screen */
X };
X
X/*
X * Color Palette Commands
X */
X
XCopyRGBCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Gadget *gadget;
X register LONG rgb, pen;
X
X /* Need contour selection to complete */
X
X gadget = (struct Gadget *) Msg->IAddress;
X
X if (Msg->Class == GADGETDOWN) {
X
X if (gadget->GadgetID == PALCOPY) { /* Copy command gadget */
X
X SetToPointer();
X State = COPYRGBSTATE;
X } else {
X
X if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
X
X /* Copy the RGBs from CurPen to NewPen */
X
X pen = GADG_NUM(gadget->GadgetID);
X rgb = GetRGB4(vp->ColorMap, CurPen);
X SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb);
X SaveRGBs(CurPict);
X
X State = IDLESTATE;
X }
X }
X }
X}
X
XSpreadRGBCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Gadget *gadget;
X register LONG pen;
X
X /* Need contour selection to complete */
X
X gadget = (struct Gadget *) Msg->IAddress;
X
X if (Msg->Class == GADGETDOWN) {
X
X if (gadget->GadgetID == PALRANGE) { /* Spread command gadget */
X
X SetToPointer();
X State = SPREADRGBSTATE;
X } else {
X
X if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
X
X /* Spread the RGBs from CurPen to NewPen */
X
X pen = GADG_NUM(gadget->GadgetID);
X ColorRange(CurPen, pen);
X SaveRGBs(CurPict);
X
X State = IDLESTATE;
X }
X }
X }
X}
X
XExchangeRGBCmd(Msg)
X struct IntuiMessage *Msg;
X{
X register LONG rgb, rgb2, pen;
X struct Gadget *gadget;
X
X /* Need contour selection to complete */
X
X gadget = (struct Gadget *) Msg->IAddress;
X
X if (Msg->Class == GADGETDOWN) {
X
X if (gadget->GadgetID == PALEXCG) { /* Exchange command gadget */
X
X SetWithPointer();
X State = XCHGRGBSTATE;
X } else {
X
X if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
X
X /* exchange the RGBs in CurPen and NewPen */
X
X pen = GADG_NUM(gadget->GadgetID);
X rgb = GetRGB4(vp->ColorMap, CurPen);
X rgb2 = GetRGB4(vp->ColorMap, pen);
X SetRGB4(vp, CurPen, rgb2 >> 8, rgb2 >> 4, rgb2 );
X SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb );
X SaveRGBs(CurPict);
X
X State = IDLESTATE;
X }
X }
X }
X}
X
XSlideRGBCmd(Msg)
X struct IntuiMessage *Msg;
X{
X struct Gadget *gadget;
X
X gadget = (struct Gadget *) Msg->IAddress;
X
X switch( Msg->Class ) {
X
X case GADGETDOWN: /* Start RGB slide */
X StartBarDrag();
X State = SLIDERGBSTATE;
X break;
X
X case MOUSEMOVE:
X ModifyColors(); /* change RGB colors */
X break;
X
X case GADGETUP: /* Stop the RGB slide */
X ModifyColors();
X SaveRGBs(CurPict);
X State = IDLESTATE;
X break;
X }
X}
X
XSetCurPen( pen )
X int pen;
X{
X BoxPen( CurPen, NORMALPEN );
X CurPen = pen;
X SetColorProps(pen);
X BoxPen( CurPen, MEDIUMPEN );
X SaveRGBs( CurPict );
X}
X
X/*
X * Blend a range of colors between two pens
X */
XColorRange(first, last)
X LONG first, last;
X{
X LONG i;
X register LONG whole, redfraction, greenfraction, bluefraction;
X register USHORT rgb;
X LONG firstred, firstgreen, firstblue;
X LONG lastred, lastgreen, lastblue;
X LONG workred, workgreen, workblue;
X
X if (first > last) {
X i = first;
X first = last;
X last = i;
X }
X
X /* I need to see a spread of at least two, where there's at least one
X * spot between the endpoints, else there's no work to do so I
X * might as well just return now.
X */
X if (first >= last - 1) return;
X
X rgb = GetRGB4(vp->ColorMap, first);
X firstred = (rgb >> 8) & 0xF;
X firstgreen = (rgb >> 4) & 0xF;
X firstblue = (rgb >> 0) & 0xF;
X
X rgb = GetRGB4(vp->ColorMap, last);
X lastred = (rgb >> 8) & 0xF;
X lastgreen = (rgb >> 4) & 0xF;
X lastblue = (rgb >> 0) & 0xF;
X
X whole = (lastred - firstred) << 16;
X redfraction = whole / (last - first);
X whole = (lastgreen - firstgreen) << 16;
X greenfraction = whole / (last - first);
X whole = (lastblue - firstblue) << 16;
X bluefraction = whole / (last - first);
X
X for (i = first + 1; i < last; i++)
X {
X lastred = (redfraction * (i - first) + 0x8000) >> 16;
X workred = firstred + lastred;
X lastgreen = (greenfraction * (i - first) + 0x8000) >> 16;
X workgreen = firstgreen + lastgreen;
X lastblue = (bluefraction * (i - first) + 0x8000) >> 16;
X workblue = firstblue + lastblue;
X SetRGB4(vp, i, workred, workgreen, workblue);
X }
X} /* ColorRange */
X
X/*
X * Modify the colors in the current pen
X */
XModifyColors( )
X{
X register LONG newred, newgreen, newblue;
X
X newred = ((struct PropInfo *)
X PalGads.RedPot->SpecialInfo)->VertPot >> 12;
X newgreen = ((struct PropInfo *)
X PalGads.GreenPot->SpecialInfo)->VertPot >> 12;
X newblue = ((struct PropInfo *)
X PalGads.BluePot->SpecialInfo)->VertPot >> 12;
X
X newred = 0xF ^ newred;
X newgreen = 0xF ^ newgreen;
X newblue = 0xF ^ newblue;
X
X PrintRGB( newred, newgreen, newblue );
X
X SetRGB4(vp, CurPen, newred, newgreen, newblue);
X} /* ModifyColors */
X
XPrintRGB( r, g, b )
X LONG r,g,b;
X{
X PrintGad( PalGads.RedPot, r );
X PrintGad( PalGads.GreenPot, g );
X PrintGad( PalGads.BluePot, b );
X}
X
XPrintGad( gadget, Color )
X register struct Gadget *gadget;
X LONG Color;
X{
X register struct IntuiText *SaveIntui, *IntuiText = gadget->GadgetText;
X
X char d[4];
X
X SaveIntui = IntuiText;
X
X Color &= 0xf;
X sprintf( d, "%x", Color );
X
X d[0] = toupper(d[0]);
X
X IntuiText = IntuiText->NextText;
X
X IntuiText->IText[0] = d[0];
X
X IntuiText = IntuiText->NextText;
X
X IntuiText->IText[0] = d[0];
X
X PrintIText( PalWind->RPort, SaveIntui, gadget->LeftEdge, gadget->TopEdge);
X}
X
X/*
X * Reflect a pen's new color in the proportional gadget
X */
XSetColorProps(pen)
X LONG pen;
X{
X register LONG rgb, red, green, blue;
X
X if (PalWind == NULL)
X return;
X
X pen &= Num_vp_Colors - 1;
X
X rgb = GetRGB4(vp->ColorMap, pen);
X
X red = 0xF - ((rgb >> 8) & 0xF);
X green = 0xF - ((rgb >> 4) & 0xF);
X blue = 0xF - (rgb & 0xF);
X
X red |= (red << 4);
X red |= (red << 8);
X green |= (green << 4);
X green |= (green << 8);
X blue |= (blue << 4);
X blue |= (blue << 8);
X
X NewModifyProp(PalGads.RedPot, PalWind,NULL,FREEVERT|PROPBORDERLESS,
X 0L,red,0L,0xfffL,1L);
X NewModifyProp(PalGads.GreenPot,PalWind,NULL,FREEVERT|PROPBORDERLESS,
X 0L,green,0L,0xfffL,1L);
X NewModifyProp(PalGads.BluePot, PalWind,NULL,FREEVERT|PROPBORDERLESS,
X 0L,blue,0L,0xfffL,1L);
X} /* SetColorProps */
X
XBoxPen(BoxPen, DrawPen)
X LONG BoxPen, DrawPen;
X{
X register LONG Top, Bot, Left, Right;
X register ULONG row, column;
X
X#define PALTOP (PENTOP - 1)
X#define PALLEFT (PENLEFT - 1)
X#define PENWIDTH (4 << XScale)
X#define PENHEIGHT (4 << YScale)
X#define PENXPITCH (6 << XScale)
X#define PENYPITCH (6 << YScale)
X
X if (PalWind == NULL)
X return;
X
X column = BoxPen/8;
X
X row = BoxPen - column*8;
X
X SetAPen(PalWind->RPort, DrawPen);
X
X Left = PALLEFT + PENXPITCH * column;
X Top = PALTOP + PENYPITCH * row;
X Right = Left + PENWIDTH + 2 + XScale;
X Bot = Top + PENHEIGHT + 2 + YScale;
X
X Move(PalWind->RPort, Left, Top);
X Draw(PalWind->RPort, Right, Top);
X
X if (DrawPen == HIGHLIGHTPEN) SetAPen(PalWind->RPort, SHADOWPEN);
X
X Draw(PalWind->RPort, Right, Bot);
X Draw(PalWind->RPort, Left, Bot);
X
X SetAPen(PalWind->RPort, DrawPen);
X
X Draw(PalWind->RPort, Left, Top + 1);
X
X if (DrawPen) {
X row = GetRGB4(vp->ColorMap, BoxPen & (Num_vp_Colors - 1));
X PrintRGB( (long) row >> 8, (long) row >> 4, (long) row );
X }
X}
X
Xstatic LONG WindowWidth;
Xstatic LONG WindowHeight;
Xstatic LONG BorderLeft;
X
Xstatic struct Border *PensBorder;
X/*
X * Allocate all the gadgets for the color palette window
X */
Xstruct Gadget *MakePalette()
X{
X struct Gadget *FirstGadget;
X register struct Gadget *NextGadget;
X register LONG i,Left,x,y,c = 0;
X
X struct IntuiText *Text, *NextText;
X struct PropInfo *PropInfo;
X
X LONG fourx = 4 << XScale;
X LONG foury = 4 << YScale;
X
X char *str;
X
X Left = PENLEFT;
X
X FirstGadget = NextGadget =
X MakeBool( Left, PENTOP, fourx, foury, 0, PALPEN, GADGIMAGE );
X
X if ( FirstGadget == NULL ) goto error;
X
X i = 1 << (screen->BitMap.Depth);
X
X for (x = 0; x < 6*8 && i > 0; x += 6) {
X for (y = 0; y < 6*8 && i > 0; y += 6) {
X if (c != 0) {
X
X NextGadget->NextGadget =
X MakeBool( Left, (y<<YScale)+PENTOP, fourx, foury, c, PALPEN+c,
X GADGIMAGE);
X
X if ((NextGadget = NextGadget->NextGadget) == NULL) goto error;
X }
X c++;
X i--;
X }
X Left += 6 << XScale;
X }
X WindowHeight = ((6*8) << YScale) + PENTOP + 6;
X
X c = ((y + 1) << YScale) + 2;
X
X if ( c > WindowHeight ) {
X WindowHeight = c + 4;
X }
X
X PensBorder = ShadowBorder( BEVELEDUP, 4, 12, Left - 2, c+1);
X
X if (PensBorder == NULL) goto error;
X
X Left += 9;
X
X BorderLeft = Left - 1;
X
X i = -2 * ( XScale ^ 1 );
X
X for (x = y = 0; y < 3; x += 10, y++) {
X
X NextGadget->NextGadget = MakePot( Left + x, 22, fourx,
X WindowHeight - 35, PALPOT, y);
X NextGadget = NextGadget->NextGadget;
X
X if ( NextGadget == NULL ) goto error;
X
X NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
X NextGadget->GadgetText = Text =
X ShadowIntui("0", i, WindowHeight - 32 );
X if ( Text == NULL ) goto error;
X
X PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
X PropInfo->VertBody = 0xfff;
X
X switch (y) {
X case 0: PalGads.RedPot = NextGadget;
X str = "R";
X break;
X
X case 1: PalGads.GreenPot = NextGadget;
X str = "G";
X break;
X
X case 2: PalGads.BluePot = NextGadget;
X str = "B";
X break;
X }
X NextText = Text;
X
X while ( NextText->NextText ) {
X NextText = NextText->NextText;
X }
X
X NextText->NextText = ShadowIntui( str, i, -11 );
X
X if ( NextText->NextText == NULL ) goto error;
X }
X Left += 32;
X
X for (c = 0, x = 0; x < 17*3; x += 17) {
X
X NextGadget->NextGadget =
X MakeBool( Left, x + 11, 54, 13, 1, PALCNTL+c, NULL);
X
X NextGadget = NextGadget->NextGadget;
X
X if ( NextGadget == NULL) goto error;
X
X switch (c) {
X case 0: NextGadget->GadgetText =
X ShadowIntui("Copy", 12,3);
X break;
X
X case 1: NextGadget->GadgetText =
X ShadowIntui("Spread",4,3);
X break;
X
X case 2: NextGadget->GadgetText =
X ShadowIntui("Exchg", 8,3);
X break;
X }
X c++;
X }
X WindowWidth = Left + 59;
X
X return(FirstGadget);
X
Xerror:
X FreeBorder( PensBorder );
X FreeGadgets( FirstGadget );
X return( NULL );
X} /* MakePalette */
X
Xstatic struct Gadget *PalGadgets;
X
X/*
X * Open the Palette window
X */
XOpenPalWind()
X{
X struct Window *OpenMyWind();
X
X register struct Gadget *gadget;
X register struct RastPort *Rp;
X LONG fourx = 4 << XScale;
X
X if (CurPict == NULL)
X return;
X
X if ( PalWind == NULL ) {
X
X gadget = MakePalette();
X
X if ( gadget == NULL ) {
X DispErrMsg("Couldn't get palette gadgets", 0 );
X return;
X }
X
X PalWind = OpenMyWind( &NewPal, screen, NULL, WindowWidth, WindowHeight);
X
X if ( PalWind != NULL ) {
X
X ModifyIDCMP( PalWind, (long)
X PalWind->IDCMPFlags | MOUSEBUTTONS | MOUSEMOVE );
X
X Rp = PalWind->RPort;
X
X SetAPen( Rp, NORMALPEN );
X RectFill( Rp, LEFTMARG, TOPMARG,
X WindowWidth,WindowHeight);
X
X BorderWindow( PalWind );
X
X PalGadgets = gadget;
X
X AddGList( PalWind, gadget, -1, -1);
X
X RefreshGadgets( gadget, PalWind, NULL );
X
X DrawBorder( Rp, PensBorder, 0L, 0L );
X FreeBorder( PensBorder );
X
X CurPen &= Num_vp_Colors - 1;
X
X BoxPen( CurPen, MEDIUMPEN );
X SetColorProps( CurPen );
X }
X } else {
X WindowToFront( PalWind );
X }
X PaletteOpen = 1;
X} /* OpenPalWind */
X
X/*
X * Close the Palette window
X */
XClosePalWind()
X{
X if (PalWind != NULL) {
X
X NewPal.LeftEdge = PalWind->LeftEdge;
X NewPal.TopEdge = PalWind->TopEdge;
X
X CloseMyWind(PalWind,PalGadgets);
X PalGadgets = NULL;
X }
X PalWind = NULL;
X} /* ClosePalWind */
X
SHAR_EOF
echo "End of archive 7 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit